package com.qding.park.manager.service.core.facade.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.DocumentCallbackHandler;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.qding.park.adapter.ark.adapter.constant.ArkConstant;
import com.qding.park.adapter.ark.adapter.entity.ArkCarInfo;
import com.qding.park.adapter.ark.adapter.entity.ArkCarOwnerInfo;
import com.qding.park.adapter.ark.adapter.entity.ArkFeeStandard;
import com.qding.park.adapter.ark.adapter.entity.ArkFeeStandardInterval;
import com.qding.park.adapter.ark.adapter.entity.ArkOwnerInfo;
import com.qding.park.adapter.ark.adapter.entity.ArkParkFee;
import com.qding.park.adapter.ark.adapter.entity.ArkSyncLog;
import com.qding.park.adapter.ark.adapter.impl.BaseDataAdapterImpl;
import com.qding.park.adapter.ark.adapter.util.FtpCxvAnalysis;
import com.qding.park.common.core.constant.MongodbConstant;
import com.qding.park.common.core.exceptions.BaseException;
import com.qding.park.common.core.exceptions.ExceptionMessage;
import com.qding.park.common.core.exceptions.business.manager.service.ServiceCoreException;
import com.qding.park.common.utils.DateUtils;
import com.qding.park.common.utils.ListUtil;
import com.qding.park.common.utils.csv.CsvParserHelper;
import com.qding.park.common.utils.csv.CsvParserHelper.ParserIterator;
import com.qding.park.common.utils.string.StringUtil;
import com.qding.park.manager.cache.ParkCacheInter;
import com.qding.park.manager.cache.UserCacheInter;
import com.qding.park.manager.facade.core.service.ConfDateFacade;
import com.qding.park.manager.pojo.SupplyEnum;
import com.qding.park.manager.pojo.TbCar;
import com.qding.park.manager.pojo.TbParkspace;
import com.qding.park.manager.pojo.TbUserInfo;
import com.qding.park.manager.pojo.enums.CardStatuEnum;
import com.qding.park.manager.pojo.enums.RecordStatusEnum;
import com.qding.park.manager.pojo.enums.UserTypeEnum;
import com.qding.park.manager.pojo.noncore.NcArkDataInitInfo;
import com.qding.park.manager.service.core.atomic.distributed.UserDBAtomic;
import com.qding.park.manager.service.core.dao.MongodbDao;
import com.qding.park.manager.service.core.mapper.QdpkParkspaceMapper;
import com.qding.park.manager.service.core.mapper.TbCarMapper;
import com.qding.park.manager.service.core.mapper.TbParkspaceMapper;
import com.qding.park.manager.service.core.mapper.TbUserInfoMapper;
import com.qding.park.manager.service.core.mapper.model.QdpkParkspace;
import com.qding.park.manager.service.core.mapper.model.QdpkParkspaceExample;
import com.qding.park.target.common.entity.AdParkInfo;
import com.univocity.parsers.csv.CsvParser;
import com.univocity.parsers.csv.CsvParserSettings;

/**
 * @ClassName ARKConfDataFacadeImpl
 * @Description TODO(方舟 基础数据获取服务)
 * @author LeiYang
 * @Date 2017年5月4日 下午5:04:42
 * @version 1.0.0
 */
@Service("confDateFacade_13")
public class ARKConfDataFacadeImpl implements ConfDateFacade {

	private static final Logger _log = LoggerFactory.getLogger(ARKConfDataFacadeImpl.class);

	/**
	 * @Field @baseDataAdapter : TODO(方舟基础数据接口)
	 */
	@Autowired
	private BaseDataAdapterImpl baseDataAdapter;

	/**
	 * @Fields mongoTemplate : TODO（mongodb操作模板）
	 */
	@Autowired
	private MongoTemplate mongoTemplate;

	@Autowired
	private UserDBAtomic userDBAtomic;

	@Autowired
	private QdpkParkspaceMapper tbParkspaceMapper;

	@Autowired
	private UserCacheInter userCacheInter;

	@Autowired
	private ParkCacheInter parkCacheInter;

	@Autowired
	private TbUserInfoMapper tbUserInfoMapper;

	@Autowired
	private TbCarMapper tbCarMapper;

	/**
	 * @Description (TODO检查是否初始化)
	 * @return
	 */
	private boolean isInit() {
		Criteria criteria = new Criteria();
		criteria.and("supplyId").is(SupplyEnum.ARK.getValue());
		Query query = new Query();
		query.addCriteria(criteria);
		NcArkDataInitInfo initInfo = mongoTemplate.findOne(query, NcArkDataInitInfo.class,
				MongodbConstant.TABLENAME_ARK_DATA_INIT);

		if (initInfo == null || NcArkDataInitInfo.NOT_INIT.equals(initInfo.getInit())) {
			return false;
		}

		return true;

	}

	/**
	 * @Description (TODO清空日志表)
	 */
	private void cleanArkSyncLogTable() {
		mongoTemplate.dropCollection(MongodbConstant.TABLENAME_ARK_SYNC_LOG);
	}

	/**
	 * @Description (TODO初始化文件回滚)
	 */
	private void rollBackInitCopyFile() {
		this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_OWNER_INFO);
		this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_CAR_INFO);
		this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_CAROWER_INFO);
		this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_FEE_STANDARD);
		this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_FEE_STANDARD_INTERVAL);
	}

	private <T> void saveBatchCsvFile(ParserIterator userParserIterator, String tableName, Class<T> t)
			throws InstantiationException, IllegalAccessException {
		FtpCxvAnalysis csvAnalysis = new FtpCxvAnalysis();
		String[] row = null;
		int rowNum = 0;
		List<T> listBean = new ArrayList<T>();
		int maxNum = 500;
		while ((row = userParserIterator.parseNext()) != null) {
			if (rowNum == 0) {
				csvAnalysis.headeAnalysis(row);
			} else {
				// 解析文件件体
				T bean = csvAnalysis.bodyAnalysis(row, t);
				listBean.add(bean);
				if (listBean.size() == maxNum) {
					mongoTemplate.insert(listBean, tableName);
					listBean.clear();
				}
			}
			rowNum++;
		}

		if (listBean.size() > 0) {
			mongoTemplate.insert(listBean, tableName);
		}
		userParserIterator.stopParsing();// 关闭连接
	}

	private void saveUserInit(File userInitfile) throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(userInitfile, ArkConstant.CSV_LINE_SEPARATOR);
		saveBatchCsvFile(userParserIterator, MongodbConstant.TABLENAME_OWNER_INFO, ArkOwnerInfo.class);
	}

	private void saveCarInit(File carInitfile) throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(carInitfile, ArkConstant.CSV_LINE_SEPARATOR);
		saveBatchCsvFile(userParserIterator, MongodbConstant.TABLENAME_CAR_INFO, ArkCarInfo.class);

	}

	private void saveCarOwerInit(File carOwnerInitfile)
			throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(carOwnerInitfile,
				ArkConstant.CSV_LINE_SEPARATOR);
		saveBatchCsvFile(userParserIterator, MongodbConstant.TABLENAME_CAROWER_INFO, ArkCarOwnerInfo.class);

	}

	private void saveFeeInit(File carOwnerInitfile) throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(carOwnerInitfile,
				ArkConstant.CSV_LINE_SEPARATOR);
		saveBatchCsvFile(userParserIterator, MongodbConstant.TABLENAME_FEE_STANDARD, ArkFeeStandard.class);

	}

	private void saveFeeIntervalInit(File carOwnerInitfile)
			throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(carOwnerInitfile,
				ArkConstant.CSV_LINE_SEPARATOR);
		saveBatchCsvFile(userParserIterator, MongodbConstant.TABLENAME_FEE_STANDARD_INTERVAL,
				ArkFeeStandardInterval.class);

	}

	private void saveParkFeeInit(File carOwnerInitfile)
			throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(carOwnerInitfile,
				ArkConstant.CSV_LINE_SEPARATOR);
		saveBatchCsvFile(userParserIterator, MongodbConstant.TABLENAME_PARK_FEE, ArkParkFee.class);

	}

	/**
	 * @Description (TODO标记已经初始化)
	 */
	private void arkInited() {
		Criteria criteria = new Criteria();
		criteria.and("supplyId").is(SupplyEnum.ARK.getValue());
		Query query = new Query();
		query.addCriteria(criteria);

		Update update = new Update();
		update.set("init", NcArkDataInitInfo.INITED);
		update.set("supplyId", SupplyEnum.ARK.getValue());
		update.set("create_date", new Date());
		update.set("update_date", new Date());

		this.mongoTemplate.upsert(query, update, MongodbConstant.TABLENAME_ARK_DATA_INIT);

	}

	private void removeFile(File file) {
		File parentFile = null;
		if (file.exists()) {
			parentFile = file.getParentFile();
			file.delete();
		}
		if (parentFile != null && parentFile.exists()) {
			parentFile.delete();
		}
	}

	/**
	 * @Description (TODO执行初始化数据)
	 * @throws FileNotFoundException
	 */
	private boolean initCopyFile() {
		try {
			// 清空日志表
			cleanArkSyncLogTable();
			this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_OWNER_INFO);// 删除
			this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_CAR_INFO);
			this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_CAROWER_INFO);
			this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_FEE_STANDARD);
			this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_FEE_STANDARD_INTERVAL);
			this.mongoTemplate.dropCollection(MongodbConstant.TABLENAME_PARK_FEE);
			// 获取用户初始化文件
			File userInitfile = baseDataAdapter.getUserInfoInitFile();
			// 车辆初始化文件
			File carInitfile = baseDataAdapter.getCarInitFile();
			// 车账号初始化文件
			File carOwnerInitfile = baseDataAdapter.getCarOwnerInitFile();

			// 临停收费标准
			File carFeeStandardInitfile = baseDataAdapter.getFeeStandardInitFile();
			// 区间/阶梯单价表
			File carFeeStandardIntervalInitfile = baseDataAdapter.getFeeStandardIntervalInitFile();

			// 临停费项标准信息
			File parkFee = baseDataAdapter.getParkFeeInitFile();

			saveUserInit(userInitfile);// 用户信息表 初始csv
			saveCarInit(carInitfile);// 车辆信息表 初始csv
			saveCarOwerInit(carOwnerInitfile);// 车账号信息表 初始csv
			saveFeeInit(carFeeStandardInitfile);// 计费规则 信息表 初始csv
			saveFeeIntervalInit(carFeeStandardIntervalInitfile);// 区间/阶梯单价表
																// 初始csv
			saveParkFeeInit(parkFee);// 临停费项标准信息表 初始csv
			arkInited();// 标记已经初始化

			// 删除下载的文件
			FileUtils.deleteDirectory(userInitfile.getParentFile());
			FileUtils.deleteDirectory(carInitfile.getParentFile());
			FileUtils.deleteDirectory(carOwnerInitfile.getParentFile());
			FileUtils.deleteDirectory(carFeeStandardInitfile.getParentFile());
			FileUtils.deleteDirectory(carFeeStandardIntervalInitfile.getParentFile());
			FileUtils.deleteDirectory(parkFee.getParentFile());
			return true;
		} catch (Exception e) {
			_log.error(e.getMessage(), e);
			rollBackInitCopyFile();
			return false;
		}

	}

	/**
	 * @Description (TODO得到增量copy的日志最大时间)
	 * @return
	 */
	private Date getArkSyncTime(String tableNmae) {
		Criteria criteria = new Criteria();
		criteria.and("tableName").is(tableNmae);
		Query query = new Query();
		query.addCriteria(criteria);
		query.with(new Sort(new Order(Direction.DESC, "fileTime")));

		ArkSyncLog log = mongoTemplate.findOne(query, ArkSyncLog.class, MongodbConstant.TABLENAME_ARK_SYNC_LOG);
		if (log == null) {
			return null;
		} else {
			return log.getFileTime();
		}
	}

	private static class MapKeyComparator implements Comparator<Long> {

		@Override
		public int compare(Long str1, Long str2) {

			return str1.compareTo(str2);
		}
	}

	private Date getTimeByfilename(String fileName) {
		Date date = DateUtils.parseDate(getTimestrByfilename(fileName), DateUtils.DATE_FORMAT_DATEONLY);
		return date;
	}

	private String getTimestrByfilename(String fileName) {
		String name = fileName.substring(0, fileName.lastIndexOf("."));// 去掉后缀名
		String timestr = name.substring(name.lastIndexOf("_") + 1);
		return timestr;
	}

	/**
	 * @Description (TODO对文件列表按日期排序)
	 * @return
	 */
	private List<File> sortFile(List<File> files) {
		Map<Long, Integer> map = new TreeMap<Long, Integer>(new MapKeyComparator());

		for (int i = 0; i < files.size(); i++) {
			String fileName = files.get(i).getName();
			String timestr = getTimestrByfilename(fileName);
			Date date = DateUtils.parseDate(timestr, DateUtils.DATE_FORMAT_DATEONLY);
			map.put(date.getTime(), i);
		}

		List<File> tempFiles = new ArrayList<File>();
		for (Map.Entry<Long, Integer> entry : map.entrySet()) {
			tempFiles.add(files.get(entry.getValue()));
		}

		return tempFiles;
	}

	private <T> void updateOne(String tableName, T bean) {
		Query query = new Query();
		Criteria criteria = new Criteria();
		query.addCriteria(criteria);
		Update update = new Update();
		if (bean instanceof ArkCarInfo) {
			criteria.and("car_id").is(((ArkCarInfo) bean).getCar_id());
			update.set("car_id", ((ArkCarInfo) bean).getCar_id());
			update.set("car_no", ((ArkCarInfo) bean).getCar_no());
			update.set("car_type", ((ArkCarInfo) bean).getCar_type());
		} else if (bean instanceof ArkCarOwnerInfo) {
			criteria.and("car_id").is(((ArkCarOwnerInfo) bean).getCar_id());
			update.set("car_id", ((ArkCarOwnerInfo) bean).getCar_id());
			update.set("car_no", ((ArkCarOwnerInfo) bean).getCar_no());
			update.set("region_id", ((ArkCarOwnerInfo) bean).getRegion_id());
			update.set("person_id", ((ArkCarOwnerInfo) bean).getPerson_id());
		} else if (bean instanceof ArkOwnerInfo) {
			criteria.and("PERSON_ID").is(((ArkOwnerInfo) bean).getPERSON_ID());
			update.set("PERSON_ID", ((ArkOwnerInfo) bean).getPERSON_ID());
			update.set("PERSON_NAME", ((ArkOwnerInfo) bean).getPERSON_NAME());
			update.set("TELPHONE", ((ArkOwnerInfo) bean).getTELPHONE());
			update.set("OA_USER_ID", ((ArkOwnerInfo) bean).getOA_USER_ID());
		} else if (bean instanceof ArkFeeStandard) {
			criteria.and("std_id").is(((ArkFeeStandard) bean).getStd_id());
			update.set("std_id", ((ArkFeeStandard) bean).getStd_id());
			update.set("std_name", ((ArkFeeStandard) bean).getStd_name());
			update.set("std_code", ((ArkFeeStandard) bean).getStd_code());
			update.set("std_desc", ((ArkFeeStandard) bean).getStd_desc());
			update.set("calc_mode", ((ArkFeeStandard) bean).getCalc_mode());
			update.set("ladder", ((ArkFeeStandard) bean).getLadder());
			update.set("std_price", ((ArkFeeStandard) bean).getStd_price());
			update.set("free_unit", ((ArkFeeStandard) bean).getFree_unit());
			update.set("quota_day", ((ArkFeeStandard) bean).getQuota_day());
			update.set("quota_mon", ((ArkFeeStandard) bean).getQuota_mon());
			update.set("effective_date", ((ArkFeeStandard) bean).getEffective_date());
			update.set("expiry_date", ((ArkFeeStandard) bean).getExpiry_date());
			update.set("is_del", ((ArkFeeStandard) bean).getIs_del());

		} else if (bean instanceof ArkFeeStandardInterval) {
			criteria.and("id").is(((ArkFeeStandardInterval) bean).getId());
			update.set("id", ((ArkFeeStandardInterval) bean).getId());
			update.set("std_id", ((ArkFeeStandardInterval) bean).getStd_id());
			update.set("begin_value", ((ArkFeeStandardInterval) bean).getBegin_value());
			update.set("end_value", ((ArkFeeStandardInterval) bean).getEnd_value());
			update.set("calc_mode", ((ArkFeeStandardInterval) bean).getCalc_mode());
			update.set("price", ((ArkFeeStandardInterval) bean).getPrice());
			update.set("is_del", ((ArkFeeStandardInterval) bean).getIs_del());
		} else if (bean instanceof ArkParkFee) {
			criteria.and("park_id").is(((ArkParkFee) bean).getPark_id());
			update.set("park_id", (((ArkParkFee) bean).getPark_id()));
			update.set("fee_id", (((ArkParkFee) bean).getFee_id()));
			update.set("subject_id", (((ArkParkFee) bean).getSubject_id()));
			update.set("effect_time", (((ArkParkFee) bean).getEffect_time()));
			update.set("del_flag", (((ArkParkFee) bean).getDel_flag()));
		}

		this.mongoTemplate.upsert(query, update, tableName);

	}

	private <T> void removeOne(String tableName, T bean) {
		Query query = new Query();
		Criteria criteria = new Criteria();
		query.addCriteria(criteria);
		if (bean instanceof ArkCarInfo) {
			criteria.and("car_id").is(((ArkCarInfo) bean).getCar_id());
		} else if (bean instanceof ArkCarOwnerInfo) {
			criteria.and("car_id").is(((ArkCarOwnerInfo) bean).getCar_id());
		} else if (bean instanceof ArkOwnerInfo) {
			criteria.and("PERSON_ID").is(((ArkOwnerInfo) bean).getPERSON_ID());
		} else if (bean instanceof ArkFeeStandard) {
			criteria.and("std_id").is(((ArkFeeStandard) bean).getStd_id());

		} else if (bean instanceof ArkFeeStandardInterval) {
			criteria.and("id").is(((ArkFeeStandardInterval) bean).getId());
		} else if (bean instanceof ArkParkFee) {
			criteria.and("park_id").is(((ArkParkFee) bean).getPark_id());
		}

		this.mongoTemplate.remove(query, tableName);

	}

	private <T> boolean isRedo(String tableName, String fileTimestr, String dataLineNum) {
		Query query = new Query();
		Criteria criteria = new Criteria();
		query.addCriteria(criteria);
		criteria.and("tableName").is(tableName);
		criteria.and("fileTimeStr").is(fileTimestr);
		criteria.and("dataLineNum").is(dataLineNum);
		long total = this.mongoTemplate.count(query, MongodbConstant.TABLENAME_ARK_SYNC_LOG);
		if (total > 0) {
			return true;
		} else {
			return false;
		}

	}

	private <T> void handleDayCsvFile(ParserIterator userParserIterator, String tableName, Class<T> t)
			throws InstantiationException, IllegalAccessException {
		FtpCxvAnalysis csvAnalysis = new FtpCxvAnalysis();
		String[] row = null;
		int rowNum = 0;
		List<T> listBean = new ArrayList<T>();
		while ((row = userParserIterator.parseNext()) != null) {
			if (rowNum == 0) {
				csvAnalysis.headeAnalysis(row);
			} else {
				// 解析文件件体
				if (this.isRedo(tableName, userParserIterator.getFileTimeStr(), String.valueOf(rowNum))) {
					// 重复处理跳过
					continue;
				}

				T bean = csvAnalysis.bodyAnalysis(row, t);
				if (csvAnalysis.isDel(row)) {
					// 删除
					// this.mongoTemplate.remove(bean, tableName);
					removeOne(tableName, bean);
				} else {
					// 未删除(更新,插入)
					updateOne(tableName, bean);
				}
				// 记日志 表示已处理完成 下次就不会处理了
				ArkSyncLog synclog = new ArkSyncLog();
				synclog.setCreateTime(new Date());
				synclog.setDataLineNum(String.valueOf(rowNum));
				synclog.setFileTime(getTimeByfilename(userParserIterator.getFileName()));
				synclog.setTableName(tableName);
				synclog.setUpdateTime(new Date());
				synclog.setFileTimeStr(userParserIterator.getFileTimeStr());
				mongoTemplate.insert(synclog, MongodbConstant.TABLENAME_ARK_SYNC_LOG);
			}
			rowNum++;
		}

		if (listBean.size() > 0) {
			mongoTemplate.insert(listBean, tableName);
		}
		userParserIterator.stopParsing();// 关闭连接
	}

	/**
	 * @Description (TODO保存增量文件)
	 * @param file
	 * @param tableName
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	private void saveDayFile(File file, String tableName)
			throws IOException, InstantiationException, IllegalAccessException {
		ParserIterator userParserIterator = CsvParserHelper.beginParsing(file, ArkConstant.CSV_LINE_SEPARATOR);
		if (MongodbConstant.TABLENAME_CAR_INFO.equals(tableName)) {
			handleDayCsvFile(userParserIterator, MongodbConstant.TABLENAME_CAR_INFO, ArkCarInfo.class);
		} else if (MongodbConstant.TABLENAME_CAROWER_INFO.equals(tableName)) {
			handleDayCsvFile(userParserIterator, MongodbConstant.TABLENAME_CAROWER_INFO, ArkCarOwnerInfo.class);
		} else if (MongodbConstant.TABLENAME_OWNER_INFO.equals(tableName)) {
			handleDayCsvFile(userParserIterator, MongodbConstant.TABLENAME_OWNER_INFO, ArkOwnerInfo.class);
		} else if (MongodbConstant.TABLENAME_FEE_STANDARD.equals(tableName)) {
			handleDayCsvFile(userParserIterator, MongodbConstant.TABLENAME_FEE_STANDARD, ArkFeeStandard.class);
		} else if (MongodbConstant.TABLENAME_FEE_STANDARD_INTERVAL.equals(tableName)) {
			handleDayCsvFile(userParserIterator, MongodbConstant.TABLENAME_FEE_STANDARD_INTERVAL,
					ArkFeeStandardInterval.class);
		} else if (MongodbConstant.TABLENAME_PARK_FEE.equals(tableName)) {
			handleDayCsvFile(userParserIterator, MongodbConstant.TABLENAME_PARK_FEE, ArkParkFee.class);
		}

	}

	/**
	 * @Description (TODO处理日增量文件)
	 * @param filePrefix
	 *            文件标识 是方舟定义的
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	private void dayCopy(String filePrefix, String tableName)
			throws InstantiationException, IllegalAccessException, IOException {
		// baseDataAdapter
		Date fileTime = getArkSyncTime(tableName);
		List<File> files = null;
		if (fileTime == null) {
			// 此文件不没有同步过
			files = baseDataAdapter.getAllDayFile(filePrefix);// 下载所有的日期增量文件
		} else {
			// 上文件同步过
			List<String> timeStrs = DateUtils.daystr4DateInterval(fileTime, new Date());
			files = baseDataAdapter.getDayFile(filePrefix, timeStrs);// 下载之间的日期文件

		}

		if (ListUtil.isEmpty(files)) {
			return;
		}

		files = this.sortFile(files);

		for (File file : files) {
			// 对每个文件进行处理
			saveDayFile(file, tableName);

		}

		FileUtils.deleteDirectory(files.get(0).getParentFile());
	}

	/**
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @Description (TODO车辆日期增量文件copy)
	 */
	private void dayCarCopy() throws InstantiationException, IllegalAccessException, IOException {
		dayCopy(baseDataAdapter.CAR_FILE_PREFIX, MongodbConstant.TABLENAME_CAR_INFO);
	}

	/**
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @Description (TODO车账号日增量文件copy)
	 */
	private void dayCarOwnerCopy() throws InstantiationException, IllegalAccessException, IOException {
		dayCopy(baseDataAdapter.CAR_OWNER_PREFIX, MongodbConstant.TABLENAME_CAROWER_INFO);
	}

	/**
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @Description (TODO计费规则日增量文件copy)
	 */
	private void dayFeeStandardCopy() throws InstantiationException, IllegalAccessException, IOException {
		dayCopy(baseDataAdapter.FEE_STANDARD, MongodbConstant.TABLENAME_FEE_STANDARD);
	}

	/**
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @Description (TODO区间/阶梯单价表)
	 */
	private void dayFeeinterval() throws InstantiationException, IllegalAccessException, IOException {
		dayCopy(baseDataAdapter.FEE_STANDARD_INERVAL, MongodbConstant.TABLENAME_FEE_STANDARD_INTERVAL);
	}

	private void dayParkFee() throws InstantiationException, IllegalAccessException, IOException {
		dayCopy(baseDataAdapter.PARK_FEE, MongodbConstant.TABLENAME_PARK_FEE);
	}

	/**
	 * @Description (TODO用户信息)
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws IOException
	 */
	private void dayOwerCopy() throws InstantiationException, IllegalAccessException, IOException {
		dayCopy(baseDataAdapter.USER_FILE_PREFIX, MongodbConstant.TABLENAME_OWNER_INFO);
	}

	/**
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @Description (TODO日增量文件copy)
	 */
	private void dayCopyFile() throws InstantiationException, IllegalAccessException, IOException {
		dayOwerCopy();// 用户增量
		dayCarCopy();// 车辆增量
		dayCarOwnerCopy();// 车账号增量
		dayFeeStandardCopy();// 计费增量
		dayFeeinterval();// 区间/阶梯单价表
		dayParkFee();// 临停费项标准信息
	}

	/**
	 * @throws IOException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @Description (TODO复制文件到临时数据表里面里面)
	 */
	private void copyFile() throws InstantiationException, IllegalAccessException, IOException {
		if (!isInit()) {
			if (!initCopyFile()) {
				throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_NOT_ALL_SUCCESS.getId(), null,
						ExceptionMessage.createExceptionMessage(
								ServiceCoreException.TypeEnum.EXCEPTION_NOT_ALL_SUCCESS.getDesc(), "方舟基础数据初始化异常",
								"方舟基础数据初始化异常"));
			}
		}

		dayCopyFile();// 日增量文件 copy
	}

	private long tel2Long(String str) {

		long tel = -1L;

		try {
			tel = Long.valueOf(str);
		} catch (Exception e) {
			_log.error(e.getMessage(), e);
		}
		return tel;
	}

	/**
	 * @Description (TODO解析数据到mysql)
	 */
	private void analysisData() {

		// 解析车场数据
		List<AdParkInfo> adParklist = analysisPark();
		// 数据结构
		Map<String, String> park2project = park2project(adParklist);
		Map<String, List<String>> project2park = project2park(adParklist);
		
		//查询方舟名下所有的车场
		List<TbParkspace> parksapces=tbParkspaceMapper.selectByExample(example);
		for(TbParkspace parkspace:parksapces){
			analysisData(parkspace.getParkCode(), park2project, project2park);
		}

		// // 同步用户
		// List<ArkOwnerInfo> owers =
		// this.mongoTemplate.findAll(ArkOwnerInfo.class,
		// MongodbConstant.TABLENAME_OWNER_INFO);
		// for (ArkOwnerInfo ower : owers) {
		// TbUserInfo u = new TbUserInfo();
		// u.setTel(tel2Long(ower.getTELPHONE()));
		// u.setName(ower.getPERSON_NAME());
		// u.setUserType(UserTypeEnum.REGISTER_USER.getType());
		// userDBAtomic.register_loginUser(u);
		// }
		//
		// // 同步车场
		// List<AdParkInfo> adParkList = baseDataAdapter.getParkList();
		//
		// // 去重
		// Set<AdParkInfo> setParkInfo = new HashSet<AdParkInfo>();
		// setParkInfo.addAll(adParkList);
		//
		// // 获取ark parkFee 信息 这里面有支付主体
		// List<ArkParkFee> parkFees =
		// this.mongoTemplate.findAll(ArkParkFee.class,
		// MongodbConstant.TABLENAME_PARK_FEE);
		// Map<String, String> parkCode2subjectId =
		// parkCode2subjectId(parkFees);
		// Iterator<AdParkInfo> parkInfoSetIter = setParkInfo.iterator();
		// while (parkInfoSetIter.hasNext()) {
		// AdParkInfo adParkInfoTemp = parkInfoSetIter.next();
		//
		// String subjectId =
		// parkCode2subjectId.get(adParkInfoTemp.getParkCode());
		// QdpkParkspace parksapce = new QdpkParkspace();
		// parksapce.setParkcode(adParkInfoTemp.getParkCode());
		// parksapce.setStatus(new
		// Byte(String.valueOf(RecordStatusEnum.EFFICIENCY.getStatus())));
		// parksapce.setBjprojectid(subjectId);
		// parksapce.setCreateDate(new Date());
		// parksapce.setUpdateDate(new Date());
		// parksapce.setPropertyname(adParkInfoTemp.getParkName());
		//
		// QdpkParkspaceExample example = new QdpkParkspaceExample();
		// QdpkParkspaceExample.Criteria criteria = example.createCriteria();
		// criteria.andParkcodeEqualTo(parksapce.getParkcode());
		// List<QdpkParkspace> lists =
		// tbParkspaceMapper.selectByExample(example);
		// if (ListUtil.isEmpty(lists)) {
		// this.tbParkspaceMapper.insertSelective(parksapce);
		// } else {
		// tbParkspaceMapper.updateByExampleSelective(parksapce, example);
		// }
		//
		// }
		//
		// // 同步车辆
		// List<ArkCarInfo> carInfos =
		// this.mongoTemplate.findAll(ArkCarInfo.class,
		// MongodbConstant.TABLENAME_CAR_INFO);
		// for (ArkCarInfo carInfo : carInfos) {
		// // 根据车牌找到车账号
		// Query query = new Query();
		// Criteria criteria = new Criteria();
		// criteria.and("car_no").is(carInfo.getCar_no());
		// query.addCriteria(criteria);
		// List<ArkCarOwnerInfo> carOwners = this.mongoTemplate.find(query,
		// ArkCarOwnerInfo.class,
		// MongodbConstant.TABLENAME_CAROWER_INFO);
		// List<String> personIds = new ArrayList<String>();
		// List<String> regionIds = new ArrayList<String>();
		//
		// for (ArkCarOwnerInfo carOwner : carOwners) {
		// personIds.add(carOwner.getPerson_id());
		// regionIds.add(carOwner.getRegion_id());
		// }
		//
		// for (String personId : personIds) {
		// // 人员
		// String userId = userCacheInter.bjuserId2userId(personId);
		// if (StringUtil.isBlank(userId)) {
		// continue;
		// }
		// for (String regionId : regionIds) {
		// // 车场
		// // parkCacheInter.queryParkSpace(parkCode, supplierId);
		// // TbCar car =new TbCar();
		// // car.setUserID(Integer.valueOf(userId));
		// // car.par
		// }
		// }
		// }

	}

	private Map<String, String> parkCode2subjectId(List<ArkParkFee> parkFees) {

		Map<String, String> map = new HashMap<String, String>();

		for (ArkParkFee fee : parkFees) {
			map.put(fee.getPark_id(), fee.getSubject_id());
		}

		return map;
	}

	/**
	 * 同步车场数据
	 * 
	 * @return
	 */
	private List<AdParkInfo> analysisPark() {
		//
		return null;
	}

	/**
	 * 车场id与小区的对应关系
	 * 
	 * @return
	 */
	private Map<String, String> park2project(List<AdParkInfo> parklist) {

	}

	/**
	 * 项目与车场对应关系
	 * 
	 * @param parklist
	 * @return
	 */
	private Map<String, List<String>> project2park(List<AdParkInfo> parklist) {

	}

	/**
	 * 同步用户
	 * 
	 * @param parkCode
	 */
	private void analysisUser(String parkCode, Map<String, String> park2project,
			Map<String, List<String>> project2park) {
		String projectid = park2project.get(parkCode);

		// 查询owner_room
		Criteria criteria = new Criteria();
		criteria.and("REGION_ID").is(projectid);
		Query query = new Query();
		query.addCriteria(criteria);
		final List<String> personids = new ArrayList<String>();
		this.mongoTemplate.executeQuery(query, MongodbConstant.TABLENAME_CAROWER_ROOM, new DocumentCallbackHandler() {

			@Override
			public void processDocument(DBObject arg0) throws MongoException, DataAccessException {
				String personid = (String) arg0.get("PERSON_ID");
				personids.add(personid);
			}

		});

		for (String person : personids) {
			ArkOwnerInfo ownerinfo = this.mongoTemplate.findOne(Query.query(Criteria.where("PERSON_ID").is(person)),
					ArkOwnerInfo.class, MongodbConstant.TABLENAME_OWNER_INFO);
			TbUserInfo userInfo = new TbUserInfo();
			String tel = ownerinfo.getTELPHONE();
			String name = ownerinfo.getPERSON_NAME();
			userInfo.setName(name);
			userInfo.setSupplierUserId(person);
			userInfo.setTel(tel2Long(tel));
			userInfo.setStatus(RecordStatusEnum.EFFICIENCY.getStatus());
			userInfo.setUserType(UserTypeEnum.REGISTER_USER.getType());
			userInfo.setCreate_date(new Date());
			userInfo.setUpdate_date(new Date());
			int num = tbUserInfoMapper.update(userInfo);
			userDBAtomic.register_loginUser(userInfo);
		}
	}

	/**
	 * 同步车辆信息
	 * 
	 * @param parkCode
	 * @param park2project
	 * @param project2park
	 */
	private void analysisCar(String parkCode, Map<String, String> park2project,
			Map<String, List<String>> project2park) {
		String projectid = park2project.get(parkCode);

		// 查询此小区下的车账号列表
		final List<String> carids = new ArrayList<String>();
		final List<String> personids = new ArrayList<String>();
		// final List<ArkCarOwnerInfo>=new ArrayList<String>(ArkCarOwnerInfo);
		Criteria criteria = new Criteria();
		criteria.and("region_id").is(projectid);
		Query query = new Query();
		query.addCriteria(criteria);
		this.mongoTemplate.executeQuery(query, MongodbConstant.TABLENAME_CAROWER_INFO, new DocumentCallbackHandler() {

			@Override
			public void processDocument(DBObject arg0) throws MongoException, DataAccessException {
				String car_id = (String) arg0.get("car_id");
				String personid = (String) arg0.get("person_id");
				carids.add(car_id);
				personids.add(personid);
			}

		});

		// 查询此小区对应的车场id
		List<String> parkCodes = project2park.get("projectid");
		for (String pcode : parkCodes) {
			TbParkspace parkspace = parkCacheInter.queryParkSpace(pcode, Integer.valueOf(SupplyEnum.ARK.getValue()));
			List<TbCar> tbusercarList = new ArrayList<TbCar>();
			for (int i = 0; i < personids.size(); i++) {
				String perid = personids.get(i);// 人员id
				int userid = this.tbUserInfoMapper.queryUserBySupplierUserId(perid);
				String carid = carids.get(i);// 车辆id
				ArkCarInfo arkCar = this.mongoTemplate.findOne(Query.query(Criteria.where("car_id").is(carid)),
						ArkCarInfo.class, MongodbConstant.TABLENAME_CAR_INFO);
				String carNum = arkCar.getCar_no();
				String carType = arkCar.getCar_type();

				TbCar car = new TbCar();
				car.setParkID(parkspace.getId());
				car.setSupplierId(Integer.valueOf(SupplyEnum.ARK.getValue()));
				car.setParkName(parkspace.getParkName());
				car.setUserID(userid);
				car.setCarNum(carNum);
				car.setStatus(CardStatuEnum.NORMAL_STATUS.getStatus());
				car.setCardType(carType);
				car.setMemberName("");
				car.setIssueTime(issueTime);
				car.setOperator(operator == null ? "" : operator);
				tbusercarList.add(car);
			}

			List<TbCar> inserts = new ArrayList<TbCar>();
			List<TbCar> updates = new ArrayList<TbCar>();
			List<TbCar> dels = new ArrayList<TbCar>();
			List<TbCar> tbcarhas = tbCarMapper.listByParkid(parkspace.getId());
			Set<String> car_carnum_userid = new HashSet<String>();
			Set<String> car_carnum_userid_new = new HashSet<String>();
			for (TbCar car : tbcarhas) {
				car_carnum_userid.add(parkspace.getId() + ":" + car.getCarNum() + ":" + car.getUserID());
			}

			for (TbCar car : tbusercarList) {
				car_carnum_userid_new.add(parkspace.getId() + ":" + car.getCarNum() + ":" + car.getUserID());
			}

			for (TbCar car : tbusercarList) {
				String tag = parkspace.getId() + ":" + car.getCarNum() + ":" + car.getUserID();
				if (car_carnum_userid.contains(tag)) {
					updates.add(car);
				} else {
					inserts.add(car);
				}
			}

			for (TbCar car : tbcarhas) {
				String tag = parkspace.getId() + ":" + car.getCarNum() + ":" + car.getUserID();
				if (!car_carnum_userid_new.contains(tag)) {
					car.setStatus(CardStatuEnum.DELETED_STATUS.getStatus());
					car.setMemberName(car.getMemberName() == null ? "" : car.getMemberName());
					car.setCarSpace(car.getCarSpace() == null ? "" : car.getCarSpace());
					car.setOperator(car.getOperator() == null ? "" : car.getOperator());
					car.setCardName(car.getCardName() == null ? "" : car.getCardName());
					dels.add(car);
				}
			}

			if (!ListUtil.isEmpty(inserts)) {
				for (TbCar car : inserts) {
					tbCarMapper.insetNoExists(car);
				}

			}
			if (!ListUtil.isEmpty(updates)) {
				tbCarMapper.batchUpdate(updates);
			}
			if (!ListUtil.isEmpty(dels)) {
				tbCarMapper.batchUpdate(dels);
			}

			tbusercarList.clear();
			tbusercarList = null;
			inserts.clear();
			inserts = null;
			updates.clear();
			updates = null;
			dels.clear();
			dels = null;

		}

	}

	/**
	 * @Description (TODO解析指定车场数据)
	 * @param parkCode
	 */
	private void analysisData(String parkCode, Map<String, String> park2project,
			Map<String, List<String>> project2park) {

		// 查询对应的项目id
		analysisUser(parkCode, park2project, project2park);// 同步用户信息
		analysisCar(parkCode, park2project, project2park);// 同步车辆信息

	}

	@Override
	public void confSync() throws BaseException {

		try {
			copyFile();// 复制文件
		} catch (Exception e) {
			_log.error(e.getMessage(), e);
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_NOT_ALL_SUCCESS.getId(), e,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_NOT_ALL_SUCCESS.getDesc(), "方舟基础数据copyFile异常",
							"方舟基础数据copyFile异常"));
		}

		analysisData();// 解析数据到mysql
	}

	@Override
	public void confSync(int parkId) throws BaseException {
		try {
			copyFile();// 复制文件
		} catch (Exception e) {
			_log.error(e.getMessage(), e);
			throw new ServiceCoreException(ServiceCoreException.TypeEnum.EXCEPTION_NOT_ALL_SUCCESS.getId(), e,
					ExceptionMessage.createExceptionMessage(
							ServiceCoreException.TypeEnum.EXCEPTION_NOT_ALL_SUCCESS.getDesc(), "方舟基础数据copyFile异常",
							"方舟基础数据copyFile异常"));
		}

		// 查询车场信息
		QdpkParkspace parkspace = tbParkspaceMapper.selectByPrimaryKey(parkId);
		if (parkspace != null) {
			String parkCode = parkspace.getParkcode();
			_log.debug("车场数据同步parkcode:{}", parkCode);
			// 解析车场数据
			List<AdParkInfo> adParklist = analysisPark();
			// 数据结构
			Map<String, String> park2project = park2project(adParklist);
			Map<String, List<String>> project2park = project2park(adParklist);
			analysisData(parkCode, park2project, project2park);
		}

	}
}
